Clase 15: DPLYR, Factores, Coerce, Recycle, NA’s, tidyr

Fecha de publicación

Invalid Date

Parte 1: Trabajando con Múltiples Conjuntos de Datos

Cargar Librerías

library(tidyverse)
library(gapminder)

Cargar Conjuntos de Datos

df_gapminder_csv <- read.csv('https://raw.githubusercontent.com/javendaXgh/datos/refs/heads/master/gapminder.csv')%>%
  select(-X)%>%
  as_tibble()

df_gapminder <- gapminder

df_gastosaludmundial <- read.csv('https://raw.githubusercontent.com/UCVeconomia2024-2/scripts/refs/heads/main/data_in/clase_12/IHME/IHME_HEALTH_SPENDING_1995_2021/IHME_HEALTH_SPENDING_1995_2021_Y2024M07D23.CSV')

# info sobre este conjunto de datos disponible en
#https://ghdx.healthdata.org/record/ihme-data/global-health-spending-1995-2021
#https://github.com/UCVeconomia2024-2/scripts/tree/main/data_in/clase_12/IHME


df_ventas <- read.csv('https://raw.githubusercontent.com/UCVeconomia2024-2/scripts/refs/heads/main/data_in/df_ventas.csv')

DF Global Health Data Exchange.

Revisar contenido a forma de hacer un pre EDA (Exploratory Data Analysis)

dim(df_gastosaludmundial)
[1] 5832   84
names(df_gastosaludmundial)
 [1] "location_id"            "location_name"          "iso3"                  
 [4] "level"                  "year"                   "the_total_mean"        
 [7] "the_total_lower"        "the_total_upper"        "the_total_ppp_mean"    
[10] "the_total_ppp_lower"    "the_total_ppp_upper"    "ghes_total_mean"       
[13] "ghes_total_lower"       "ghes_total_upper"       "ghes_total_ppp_mean"   
[16] "ghes_total_ppp_lower"   "ghes_total_ppp_upper"   "ppp_total_mean"        
[19] "ppp_total_lower"        "ppp_total_upper"        "ppp_total_ppp_mean"    
[22] "ppp_total_ppp_lower"    "ppp_total_ppp_upper"    "oop_total_mean"        
[25] "oop_total_lower"        "oop_total_upper"        "oop_total_ppp_mean"    
[28] "oop_total_ppp_lower"    "oop_total_ppp_upper"    "dah_total_mean"        
[31] "dah_total_ppp_mean"     "the_per_cap_mean"       "the_per_cap_lower"     
[34] "the_per_cap_upper"      "the_per_cap_ppp_mean"   "the_per_cap_ppp_lower" 
[37] "the_per_cap_ppp_upper"  "ghes_per_cap_mean"      "ghes_per_cap_lower"    
[40] "ghes_per_cap_upper"     "ghes_per_cap_ppp_mean"  "ghes_per_cap_ppp_lower"
[43] "ghes_per_cap_ppp_upper" "ppp_per_cap_mean"       "ppp_per_cap_lower"     
[46] "ppp_per_cap_upper"      "ppp_per_cap_ppp_mean"   "ppp_per_cap_ppp_lower" 
[49] "ppp_per_cap_ppp_upper"  "oop_per_cap_mean"       "oop_per_cap_lower"     
[52] "oop_per_cap_upper"      "oop_per_cap_ppp_mean"   "oop_per_cap_ppp_lower" 
[55] "oop_per_cap_ppp_upper"  "dah_per_cap_mean"       "dah_per_cap_ppp_mean"  
[58] "ghes_per_the_mean"      "ghes_per_the_lower"     "ghes_per_the_upper"    
[61] "ppp_per_the_mean"       "ppp_per_the_lower"      "ppp_per_the_upper"     
[64] "oop_per_the_mean"       "oop_per_the_lower"      "oop_per_the_upper"     
[67] "dah_per_the_mean"       "dah_per_the_lower"      "dah_per_the_upper"     
[70] "the_per_gdp_mean"       "the_per_gdp_lower"      "the_per_gdp_upper"     
[73] "ghes_per_gdp_mean"      "ghes_per_gdp_lower"     "ghes_per_gdp_upper"    
[76] "ppp_per_gdp_mean"       "ppp_per_gdp_lower"      "ppp_per_gdp_upper"     
[79] "oop_per_gdp_mean"       "oop_per_gdp_lower"      "oop_per_gdp_upper"     
[82] "dah_per_gdp_mean"       "dah_per_gdp_lower"      "dah_per_gdp_upper"     
summary(df_gastosaludmundial[,1:10])
  location_id       location_name          iso3              level          
 Min.   :    1.00   Length:5832        Length:5832        Length:5832       
 1st Qu.:   62.75   Class :character   Class :character   Class :character  
 Median :  124.00   Mode  :character   Mode  :character   Mode  :character  
 Mean   :  957.29                                                           
 3rd Qu.:  183.25                                                           
 Max.   :44578.00                                                           
      year      the_total_mean      the_total_lower     the_total_upper    
 Min.   :1995   Min.   :3.730e+02   Min.   :2.660e+02   Min.   :5.030e+02  
 1st Qu.:2001   1st Qu.:2.811e+05   1st Qu.:2.497e+05   1st Qu.:3.153e+05  
 Median :2008   Median :1.530e+06   Median :1.389e+06   Median :1.666e+06  
 Mean   :2008   Mean   :1.226e+08   Mean   :1.202e+08   Mean   :1.251e+08  
 3rd Qu.:2015   3rd Qu.:1.214e+07   3rd Qu.:1.144e+07   3rd Qu.:1.296e+07  
 Max.   :2021   Max.   :1.016e+10   Max.   :1.006e+10   Max.   :1.027e+10  
 the_total_ppp_mean  the_total_ppp_lower
 Min.   :8.000e+00   Min.   :7.000e+00  
 1st Qu.:5.599e+05   1st Qu.:4.680e+05  
 Median :3.543e+06   Median :3.242e+06  
 Mean   :1.660e+08   Mean   :1.620e+08  
 3rd Qu.:2.599e+07   3rd Qu.:2.394e+07  
 Max.   :1.401e+10   Max.   :1.389e+10  
str(df_gastosaludmundial[,1:10])
'data.frame':   5832 obs. of  10 variables:
 $ location_id        : int  1 1 1 1 1 1 1 1 1 1 ...
 $ location_name      : chr  "Global" "Global" "Global" "Global" ...
 $ iso3               : chr  "G" "G" "G" "G" ...
 $ level              : chr  "Global" "Global" "Global" "Global" ...
 $ year               : int  1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 ...
 $ the_total_mean     : num  3.80e+09 3.91e+09 4.06e+09 4.22e+09 4.36e+09 ...
 $ the_total_lower    : num  3.57e+09 3.78e+09 3.96e+09 4.13e+09 4.28e+09 ...
 $ the_total_upper    : num  4.02e+09 4.04e+09 4.16e+09 4.31e+09 4.45e+09 ...
 $ the_total_ppp_mean : num  5.12e+09 5.28e+09 5.48e+09 5.68e+09 5.85e+09 ...
 $ the_total_ppp_lower: num  4.79e+09 5.05e+09 5.31e+09 5.53e+09 5.71e+09 ...

Listado de Países con Datos

Vamos a evaluar cuáles países disponen de datos en esta df:

unique(df_gastosaludmundial$location_name)
  [1] "Global"                                          
  [2] "High income"                                     
  [3] "Low income"                                      
  [4] "Lower-middle income"                             
  [5] "Upper-middle income"                             
  [6] "Central Europe, Eastern Europe, and Central Asia"
  [7] "High-income"                                     
  [8] "Latin America and Caribbean"                     
  [9] "North Africa and Middle East"                    
 [10] "South Asia"                                      
 [11] "Southeast Asia, East Asia, and Oceania"          
 [12] "Sub-Saharan Africa"                              
 [13] "Afghanistan"                                     
 [14] "Albania"                                         
 [15] "Algeria"                                         
 [16] "American Samoa"                                  
 [17] "Andorra"                                         
 [18] "Angola"                                          
 [19] "Antigua and Barbuda"                             
 [20] "Argentina"                                       
 [21] "Armenia"                                         
 [22] "Australia"                                       
 [23] "Austria"                                         
 [24] "Azerbaijan"                                      
 [25] "Bahamas"                                         
 [26] "Bahrain"                                         
 [27] "Bangladesh"                                      
 [28] "Barbados"                                        
 [29] "Belarus"                                         
 [30] "Belgium"                                         
 [31] "Belize"                                          
 [32] "Benin"                                           
 [33] "Bermuda"                                         
 [34] "Bhutan"                                          
 [35] "Bolivia (Plurinational State of)"                
 [36] "Bosnia and Herzegovina"                          
 [37] "Botswana"                                        
 [38] "Brazil"                                          
 [39] "Brunei Darussalam"                               
 [40] "Bulgaria"                                        
 [41] "Burkina Faso"                                    
 [42] "Burundi"                                         
 [43] "Cabo Verde"                                      
 [44] "Cambodia"                                        
 [45] "Cameroon"                                        
 [46] "Canada"                                          
 [47] "Central African Republic"                        
 [48] "Chad"                                            
 [49] "Chile"                                           
 [50] "China"                                           
 [51] "Colombia"                                        
 [52] "Comoros"                                         
 [53] "Congo"                                           
 [54] "Cook Islands"                                    
 [55] "Costa Rica"                                      
 [56] "Croatia"                                         
 [57] "Cuba"                                            
 [58] "Cyprus"                                          
 [59] "Czechia"                                         
 [60] "Côte d'Ivoire"                                   
 [61] "Democratic People's Republic of Korea"           
 [62] "Democratic Republic of the Congo"                
 [63] "Denmark"                                         
 [64] "Djibouti"                                        
 [65] "Dominica"                                        
 [66] "Dominican Republic"                              
 [67] "Ecuador"                                         
 [68] "Egypt"                                           
 [69] "El Salvador"                                     
 [70] "Equatorial Guinea"                               
 [71] "Eritrea"                                         
 [72] "Estonia"                                         
 [73] "Eswatini"                                        
 [74] "Ethiopia"                                        
 [75] "Fiji"                                            
 [76] "Finland"                                         
 [77] "France"                                          
 [78] "Gabon"                                           
 [79] "Gambia"                                          
 [80] "Georgia"                                         
 [81] "Germany"                                         
 [82] "Ghana"                                           
 [83] "Greece"                                          
 [84] "Greenland"                                       
 [85] "Grenada"                                         
 [86] "Guam"                                            
 [87] "Guatemala"                                       
 [88] "Guinea"                                          
 [89] "Guinea-Bissau"                                   
 [90] "Guyana"                                          
 [91] "Haiti"                                           
 [92] "Honduras"                                        
 [93] "Hungary"                                         
 [94] "Iceland"                                         
 [95] "India"                                           
 [96] "Indonesia"                                       
 [97] "Iran (Islamic Republic of)"                      
 [98] "Iraq"                                            
 [99] "Ireland"                                         
[100] "Israel"                                          
[101] "Italy"                                           
[102] "Jamaica"                                         
[103] "Japan"                                           
[104] "Jordan"                                          
[105] "Kazakhstan"                                      
[106] "Kenya"                                           
[107] "Kiribati"                                        
[108] "Kuwait"                                          
[109] "Kyrgyzstan"                                      
[110] "Lao People's Democratic Republic"                
[111] "Latvia"                                          
[112] "Lebanon"                                         
[113] "Lesotho"                                         
[114] "Liberia"                                         
[115] "Libya"                                           
[116] "Lithuania"                                       
[117] "Luxembourg"                                      
[118] "Madagascar"                                      
[119] "Malawi"                                          
[120] "Malaysia"                                        
[121] "Maldives"                                        
[122] "Mali"                                            
[123] "Malta"                                           
[124] "Marshall Islands"                                
[125] "Mauritania"                                      
[126] "Mauritius"                                       
[127] "Mexico"                                          
[128] "Micronesia (Federated States of)"                
[129] "Monaco"                                          
[130] "Mongolia"                                        
[131] "Montenegro"                                      
[132] "Morocco"                                         
[133] "Mozambique"                                      
[134] "Myanmar"                                         
[135] "Namibia"                                         
[136] "Nauru"                                           
[137] "Nepal"                                           
[138] "Netherlands"                                     
[139] "New Zealand"                                     
[140] "Nicaragua"                                       
[141] "Niger"                                           
[142] "Nigeria"                                         
[143] "Niue"                                            
[144] "North Macedonia"                                 
[145] "Northern Mariana Islands"                        
[146] "Norway"                                          
[147] "Oman"                                            
[148] "Pakistan"                                        
[149] "Palau"                                           
[150] "Palestine"                                       
[151] "Panama"                                          
[152] "Papua New Guinea"                                
[153] "Paraguay"                                        
[154] "Peru"                                            
[155] "Philippines"                                     
[156] "Poland"                                          
[157] "Portugal"                                        
[158] "Puerto Rico"                                     
[159] "Qatar"                                           
[160] "Republic of Korea"                               
[161] "Republic of Moldova"                             
[162] "Romania"                                         
[163] "Russian Federation"                              
[164] "Rwanda"                                          
[165] "Saint Kitts and Nevis"                           
[166] "Saint Lucia"                                     
[167] "Saint Vincent and the Grenadines"                
[168] "Samoa"                                           
[169] "San Marino"                                      
[170] "Sao Tome and Principe"                           
[171] "Saudi Arabia"                                    
[172] "Senegal"                                         
[173] "Serbia"                                          
[174] "Seychelles"                                      
[175] "Sierra Leone"                                    
[176] "Singapore"                                       
[177] "Slovakia"                                        
[178] "Slovenia"                                        
[179] "Solomon Islands"                                 
[180] "Somalia"                                         
[181] "South Africa"                                    
[182] "South Sudan"                                     
[183] "Spain"                                           
[184] "Sri Lanka"                                       
[185] "Sudan"                                           
[186] "Suriname"                                        
[187] "Sweden"                                          
[188] "Switzerland"                                     
[189] "Syrian Arab Republic"                            
[190] "Taiwan"                                          
[191] "Tajikistan"                                      
[192] "Thailand"                                        
[193] "Timor-Leste"                                     
[194] "Togo"                                            
[195] "Tokelau"                                         
[196] "Tonga"                                           
[197] "Trinidad and Tobago"                             
[198] "Tunisia"                                         
[199] "Turkmenistan"                                    
[200] "Tuvalu"                                          
[201] "Türkiye"                                         
[202] "Uganda"                                          
[203] "Ukraine"                                         
[204] "United Arab Emirates"                            
[205] "United Kingdom"                                  
[206] "United Republic of Tanzania"                     
[207] "United States Virgin Islands"                    
[208] "United States of America"                        
[209] "Uruguay"                                         
[210] "Uzbekistan"                                      
[211] "Vanuatu"                                         
[212] "Venezuela (Bolivarian Republic of)"              
[213] "Viet Nam"                                        
[214] "Yemen"                                           
[215] "Zambia"                                          
[216] "Zimbabwe"                                        

Al trabajar con conjuntos de datos de este estilo es recomendable leer la documentación que les acompaña para tener nociones sobre cuáles son los datos representados y la metodología usada para el levantamiento de los mismos.

https://ghdx.healthdata.org/record/ihme-data/global-health-spending-1995-2021

https://github.com/UCVeconomia2024-2/scripts/tree/main/data_in/clase_12/IHME

Listado de Países América

df_paises_america <- df_gapminder_csv%>%
  filter(continent=='Americas')

crear df con valores duplicados uniendo dos df’s

df_paises_america2 <- bind_rows(df_paises_america,
                                df_paises_america%>%
                                  sample_n(30)
                                )%>%
  arrange(country, year)

En la DF creada df_paises_america2 existen valores duplicados a los fines de crear un ejemplo de una DF con filas duplicadas

df_paises_america2%>%
  print(n=30) # presencia de valores duplicados
# A tibble: 330 × 6
   country   continent  year lifeExp      pop gdpPercap
   <chr>     <chr>     <int>   <dbl>    <int>     <dbl>
 1 Argentina Americas   1952    62.5 17876956     5911.
 2 Argentina Americas   1957    64.4 19610538     6857.
 3 Argentina Americas   1962    65.1 21283783     7133.
 4 Argentina Americas   1967    65.6 22934225     8053.
 5 Argentina Americas   1972    67.1 24779799     9443.
 6 Argentina Americas   1977    68.5 26983828    10079.
 7 Argentina Americas   1982    69.9 29341374     8998.
 8 Argentina Americas   1987    70.8 31620918     9140.
 9 Argentina Americas   1992    71.9 33958947     9308.
10 Argentina Americas   1997    73.3 36203463    10967.
11 Argentina Americas   1997    73.3 36203463    10967.
12 Argentina Americas   2002    74.3 38331121     8798.
13 Argentina Americas   2007    75.3 40301927    12779.
14 Bolivia   Americas   1952    40.4  2883315     2677.
15 Bolivia   Americas   1957    41.9  3211738     2128.
16 Bolivia   Americas   1962    43.4  3593918     2181.
17 Bolivia   Americas   1967    45.0  4040665     2587.
18 Bolivia   Americas   1967    45.0  4040665     2587.
19 Bolivia   Americas   1972    46.7  4565872     2980.
20 Bolivia   Americas   1977    50.0  5079716     3548.
21 Bolivia   Americas   1982    53.9  5642224     3157.
22 Bolivia   Americas   1987    57.3  6156369     2754.
23 Bolivia   Americas   1992    60.0  6893451     2962.
24 Bolivia   Americas   1997    62.0  7693188     3326.
25 Bolivia   Americas   2002    63.9  8445134     3413.
26 Bolivia   Americas   2007    65.6  9119152     3822.
27 Brazil    Americas   1952    50.9 56602560     2109.
28 Brazil    Americas   1952    50.9 56602560     2109.
29 Brazil    Americas   1957    53.3 65551171     2487.
30 Brazil    Americas   1962    55.7 76039390     3337.
# ℹ 300 more rows
dim(df_paises_america)
[1] 300   6
dim(df_paises_america2) # se incrementa por la presencia de valores duplicados
[1] 330   6

Remoción de filas duplicadas:

df_paises_america_limpio <- df_paises_america2%>%
  filter(continent=='Americas')%>%
  distinct(country, lifeExp) #, .keep_all=TRUE

dim(df_paises_america_limpio)
[1] 300   2
str(df_paises_america_limpio)
tibble [300 × 2] (S3: tbl_df/tbl/data.frame)
 $ country: chr [1:300] "Argentina" "Argentina" "Argentina" "Argentina" ...
 $ lifeExp: num [1:300] 62.5 64.4 65.1 65.6 67.1 ...
df_paises_america_limpio
# A tibble: 300 × 2
   country   lifeExp
   <chr>       <dbl>
 1 Argentina    62.5
 2 Argentina    64.4
 3 Argentina    65.1
 4 Argentina    65.6
 5 Argentina    67.1
 6 Argentina    68.5
 7 Argentina    69.9
 8 Argentina    70.8
 9 Argentina    71.9
10 Argentina    73.3
# ℹ 290 more rows

Se están removiendo con base en la repetición de dos atributos por fila, pero pudieran ser más o menos los atributos a evaluar si se repiten implicando que la repetición puede ser evaluada parcial o totalmente

Remover filas duplicadas conservando todos los atributos

df_paises_america_limpio <- df_paises_america2%>%
  filter(continent=='Americas')%>%
  distinct(country, lifeExp, .keep_all=TRUE) 

dim(df_paises_america_limpio)
[1] 300   6
str(df_paises_america_limpio)
tibble [300 × 6] (S3: tbl_df/tbl/data.frame)
 $ country  : chr [1:300] "Argentina" "Argentina" "Argentina" "Argentina" ...
 $ continent: chr [1:300] "Americas" "Americas" "Americas" "Americas" ...
 $ year     : int [1:300] 1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 ...
 $ lifeExp  : num [1:300] 62.5 64.4 65.1 65.6 67.1 ...
 $ pop      : int [1:300] 17876956 19610538 21283783 22934225 24779799 26983828 29341374 31620918 33958947 36203463 ...
 $ gdpPercap: num [1:300] 5911 6857 7133 8053 9443 ...
df_paises_america_limpio
# A tibble: 300 × 6
   country   continent  year lifeExp      pop gdpPercap
   <chr>     <chr>     <int>   <dbl>    <int>     <dbl>
 1 Argentina Americas   1952    62.5 17876956     5911.
 2 Argentina Americas   1957    64.4 19610538     6857.
 3 Argentina Americas   1962    65.1 21283783     7133.
 4 Argentina Americas   1967    65.6 22934225     8053.
 5 Argentina Americas   1972    67.1 24779799     9443.
 6 Argentina Americas   1977    68.5 26983828    10079.
 7 Argentina Americas   1982    69.9 29341374     8998.
 8 Argentina Americas   1987    70.8 31620918     9140.
 9 Argentina Americas   1992    71.9 33958947     9308.
10 Argentina Americas   1997    73.3 36203463    10967.
# ℹ 290 more rows

Extracción países de América en Gapminder que estén en datos de GastosSaludMundial

La idea es poder extraer de la df de gastos en salud los países de América que están en Gapminder, suponiendo que queremos obtener otros datos que nos permitan enriquecer nuestro análisis sobre ambos conjuntos de datos y que estos se complementen.

Obtener listado de países de América según gapminder

paises_america <- df_gapminder_csv%>%
  filter(continent=='Americas')%>%
  select(country)%>%
  distinct(country)%>% 
  pull(country)

Notar uso de función pull para extraer los resultados en la estructura de un vector. Comparar sino se usará esa última línea, cuál sería el resultado.

Ahora se evalúa cuántos países únicos contiene el vector paises_america

length(paises_america) # cdad de paises
[1] 25

Seleccionar columnas por aparición de una string en el nombre

Sabiendo que la palabra mean en inglés quiere decir promedio, a fines de ejemplificar el uso de la función select en conjunto con ends_with se propone el siguiente ejercicio:

df_gsm_mean <- df_gastosaludmundial%>%
  filter(location_name %in% paises_america)%>%
  select(location_name, year, ends_with('mean'))

Sabiendo que la df en uso contiene 31, se propone seleccionar sólo los columnas que representen valores promedio y se hace aplicación conjunta de select y ends_with('mean'). También se seleccionan las columnas “location_name” y “year” ya que van a identificar dos atributos clave, como lo son el país y año que se representa en cada fila.

Igualmente, en el paso anterior se filtraron sólo los países de América que están contenidos en el vector paises_america.

Ahora inspeccionamos los nombres de los países de df_gsm_mean:

unique(df_gsm_mean$location_name)
 [1] "Argentina"           "Brazil"              "Canada"             
 [4] "Chile"               "Colombia"            "Costa Rica"         
 [7] "Cuba"                "Dominican Republic"  "Ecuador"            
[10] "El Salvador"         "Guatemala"           "Haiti"              
[13] "Honduras"            "Jamaica"             "Mexico"             
[16] "Nicaragua"           "Panama"              "Paraguay"           
[19] "Peru"                "Puerto Rico"         "Trinidad and Tobago"
[22] "Uruguay"            

y en cuanto a las dimensiones de la df

dim(df_gsm_mean)
[1] 594  31

Existe una diferencia, ya que hay 22 países en df_gsm_mean mientras que en paises_america hay 25, lo que implica que no se filtraron todos los países que se encuentran listados.

Esto se motiva en que los nombres difieren en escritura en las dos data frame´s.

Para evaluar un mecanismo alterno se va a crear una string con todos los nombres de los países con miras de detectar coincidencias no exactas sino parciales.

La función %in% aplica para detecciones de coincidencias exactas mientras que con str_detect hace la detección parcial.

El operador | sabemos que indica OR lo que quiere decir que o aparece Argentina o aparece Bolivia o …., etc.

string_paises <- paste0(paises_america,collapse = '|')

string_paises
[1] "Argentina|Bolivia|Brazil|Canada|Chile|Colombia|Costa Rica|Cuba|Dominican Republic|Ecuador|El Salvador|Guatemala|Haiti|Honduras|Jamaica|Mexico|Nicaragua|Panama|Paraguay|Peru|Puerto Rico|Trinidad and Tobago|United States|Uruguay|Venezuela"

Nuevamente intentamos crear la df_gsm_mean:

df_gsm_mean <- df_gastosaludmundial%>%
  filter(str_detect(location_name, string_paises))%>%
  select(location_name,year, ends_with('mean'))

unique(df_gsm_mean$location_name)
 [1] "Argentina"                          "Bolivia (Plurinational State of)"  
 [3] "Brazil"                             "Canada"                            
 [5] "Chile"                              "Colombia"                          
 [7] "Costa Rica"                         "Cuba"                              
 [9] "Dominican Republic"                 "Ecuador"                           
[11] "El Salvador"                        "Guatemala"                         
[13] "Haiti"                              "Honduras"                          
[15] "Jamaica"                            "Mexico"                            
[17] "Nicaragua"                          "Panama"                            
[19] "Paraguay"                           "Peru"                              
[21] "Puerto Rico"                        "Trinidad and Tobago"               
[23] "United States Virgin Islands"       "United States of America"          
[25] "Uruguay"                            "Venezuela (Bolivarian Republic of)"

Para entender mejor el funcionamiento de str_detect consultamos la documentación.

library(stringr)
#?str_detect # consultar función

Hay que recordar que esta función está contenida en el paquete stringr que fue cargado previamente con la suite tidiverse.

Detección Países Faltantes

paises1 <- df_gastosaludmundial%>%
  filter(location_name %in% paises_america)%>%
  distinct(location_name)%>%
  pull(location_name)


paises2 <- df_gastosaludmundial%>%
  filter(str_detect(location_name, string_paises))%>%
  distinct(location_name)%>%
  pull(location_name)

paises2[paises2 %in% paises1]
 [1] "Argentina"           "Brazil"              "Canada"             
 [4] "Chile"               "Colombia"            "Costa Rica"         
 [7] "Cuba"                "Dominican Republic"  "Ecuador"            
[10] "El Salvador"         "Guatemala"           "Haiti"              
[13] "Honduras"            "Jamaica"             "Mexico"             
[16] "Nicaragua"           "Panama"              "Paraguay"           
[19] "Peru"                "Puerto Rico"         "Trinidad and Tobago"
[22] "Uruguay"            
paises2[!paises2 %in% paises1]
[1] "Bolivia (Plurinational State of)"   "United States Virgin Islands"      
[3] "United States of America"           "Venezuela (Bolivarian Republic of)"

Más adelante, en otra clase veremos cómo podemos juntar ambas data frames combinando los datos de una y otra por país haciendo joins de distinto tipo.

Parte 2: Factores

Estructura de datos que agrupa elementos en niveles o categorías. Son útiles cuando tienes variables categóricas, como género (hombre/mujer), tipo de producto (libro/revista) o cualquier otra variable que tenga un conjunto limitado de posibles valores.

library(forcats) # fue cargada previamente con tidyverse

paises_america2 <- df_gapminder%>%
  filter(continent=='Americas')%>%
  select(country)%>%
  distinct(country)%>% 
  pull(country)

paises_america2
 [1] Argentina           Bolivia             Brazil             
 [4] Canada              Chile               Colombia           
 [7] Costa Rica          Cuba                Dominican Republic 
[10] Ecuador             El Salvador         Guatemala          
[13] Haiti               Honduras            Jamaica            
[16] Mexico              Nicaragua           Panama             
[19] Paraguay            Peru                Puerto Rico        
[22] Trinidad and Tobago United States       Uruguay            
[25] Venezuela          
142 Levels: Afghanistan Albania Algeria Angola Argentina Australia ... Zimbabwe

La representación de los datos varía en formato a un vector de tipo caracter

levels(paises_america2)
  [1] "Afghanistan"              "Albania"                 
  [3] "Algeria"                  "Angola"                  
  [5] "Argentina"                "Australia"               
  [7] "Austria"                  "Bahrain"                 
  [9] "Bangladesh"               "Belgium"                 
 [11] "Benin"                    "Bolivia"                 
 [13] "Bosnia and Herzegovina"   "Botswana"                
 [15] "Brazil"                   "Bulgaria"                
 [17] "Burkina Faso"             "Burundi"                 
 [19] "Cambodia"                 "Cameroon"                
 [21] "Canada"                   "Central African Republic"
 [23] "Chad"                     "Chile"                   
 [25] "China"                    "Colombia"                
 [27] "Comoros"                  "Congo, Dem. Rep."        
 [29] "Congo, Rep."              "Costa Rica"              
 [31] "Cote d'Ivoire"            "Croatia"                 
 [33] "Cuba"                     "Czech Republic"          
 [35] "Denmark"                  "Djibouti"                
 [37] "Dominican Republic"       "Ecuador"                 
 [39] "Egypt"                    "El Salvador"             
 [41] "Equatorial Guinea"        "Eritrea"                 
 [43] "Ethiopia"                 "Finland"                 
 [45] "France"                   "Gabon"                   
 [47] "Gambia"                   "Germany"                 
 [49] "Ghana"                    "Greece"                  
 [51] "Guatemala"                "Guinea"                  
 [53] "Guinea-Bissau"            "Haiti"                   
 [55] "Honduras"                 "Hong Kong, China"        
 [57] "Hungary"                  "Iceland"                 
 [59] "India"                    "Indonesia"               
 [61] "Iran"                     "Iraq"                    
 [63] "Ireland"                  "Israel"                  
 [65] "Italy"                    "Jamaica"                 
 [67] "Japan"                    "Jordan"                  
 [69] "Kenya"                    "Korea, Dem. Rep."        
 [71] "Korea, Rep."              "Kuwait"                  
 [73] "Lebanon"                  "Lesotho"                 
 [75] "Liberia"                  "Libya"                   
 [77] "Madagascar"               "Malawi"                  
 [79] "Malaysia"                 "Mali"                    
 [81] "Mauritania"               "Mauritius"               
 [83] "Mexico"                   "Mongolia"                
 [85] "Montenegro"               "Morocco"                 
 [87] "Mozambique"               "Myanmar"                 
 [89] "Namibia"                  "Nepal"                   
 [91] "Netherlands"              "New Zealand"             
 [93] "Nicaragua"                "Niger"                   
 [95] "Nigeria"                  "Norway"                  
 [97] "Oman"                     "Pakistan"                
 [99] "Panama"                   "Paraguay"                
[101] "Peru"                     "Philippines"             
[103] "Poland"                   "Portugal"                
[105] "Puerto Rico"              "Reunion"                 
[107] "Romania"                  "Rwanda"                  
[109] "Sao Tome and Principe"    "Saudi Arabia"            
[111] "Senegal"                  "Serbia"                  
[113] "Sierra Leone"             "Singapore"               
[115] "Slovak Republic"          "Slovenia"                
[117] "Somalia"                  "South Africa"            
[119] "Spain"                    "Sri Lanka"               
[121] "Sudan"                    "Swaziland"               
[123] "Sweden"                   "Switzerland"             
[125] "Syria"                    "Taiwan"                  
[127] "Tanzania"                 "Thailand"                
[129] "Togo"                     "Trinidad and Tobago"     
[131] "Tunisia"                  "Turkey"                  
[133] "Uganda"                   "United Kingdom"          
[135] "United States"            "Uruguay"                 
[137] "Venezuela"                "Vietnam"                 
[139] "West Bank and Gaza"       "Yemen, Rep."             
[141] "Zambia"                   "Zimbabwe"                
levels(paises_america)
NULL

Niveles

Contar elementos por nivel

fct_count(paises_america, sort = FALSE,
          prop = FALSE)
# A tibble: 25 × 2
   f                      n
   <fct>              <int>
 1 Argentina              1
 2 Bolivia                1
 3 Brazil                 1
 4 Canada                 1
 5 Chile                  1
 6 Colombia               1
 7 Costa Rica             1
 8 Cuba                   1
 9 Dominican Republic     1
10 Ecuador                1
# ℹ 15 more rows

No muestra los niveles que contienen NA´s

fct_drop(paises_america)
 [1] Argentina           Bolivia             Brazil             
 [4] Canada              Chile               Colombia           
 [7] Costa Rica          Cuba                Dominican Republic 
[10] Ecuador             El Salvador         Guatemala          
[13] Haiti               Honduras            Jamaica            
[16] Mexico              Nicaragua           Panama             
[19] Paraguay            Peru                Puerto Rico        
[22] Trinidad and Tobago United States       Uruguay            
[25] Venezuela          
25 Levels: Argentina Bolivia Brazil Canada Chile Colombia Costa Rica ... Venezuela

Se retoma al revisar contenido sobre los NA´s.

Vectores con factores

Crear un vector con factores

vector_factores <- factor(sample(1:10, 20, replace = TRUE),
                          levels = 1:11)
vector_factores
 [1] 3  3  5  9  3  10 10 5  7  9  4  1  1  4  4  5  9  1  7  6 
Levels: 1 2 3 4 5 6 7 8 9 10 11
levels(vector_factores)
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11"

Remover factores mediante RBase

Usando la familia de funciones as:

as.numeric(levels(vector_factores))[vector_factores]
 [1]  3  3  5  9  3 10 10  5  7  9  4  1  1  4  4  5  9  1  7  6

Remover factores mediante paquete varhandle

# install.packages('varhandle')
library(varhandle)
unfactor(vector_factores)
 [1]  3  3  5  9  3 10 10  5  7  9  4  1  1  4  4  5  9  1  7  6

Versión factor categorías

Crear un vector con factores

categorias <- c('muy bajo','bajo','medio','alto','muy alto')
vector_fact_categorias <- factor(sample(categorias, 30, replace = TRUE))
vector_fact_categorias
 [1] medio    alto     muy bajo medio    muy bajo muy bajo medio    muy alto
 [9] muy bajo bajo     bajo     muy alto muy bajo alto     muy bajo medio   
[17] muy alto alto     muy bajo muy alto alto     medio    alto     muy alto
[25] muy bajo bajo     alto     alto     bajo     alto    
Levels: alto bajo medio muy alto muy bajo

Remover factores mediante RBase

as.character(levels(vector_fact_categorias))[vector_fact_categorias]
 [1] "medio"    "alto"     "muy bajo" "medio"    "muy bajo" "muy bajo"
 [7] "medio"    "muy alto" "muy bajo" "bajo"     "bajo"     "muy alto"
[13] "muy bajo" "alto"     "muy bajo" "medio"    "muy alto" "alto"    
[19] "muy bajo" "muy alto" "alto"     "medio"    "alto"     "muy alto"
[25] "muy bajo" "bajo"     "alto"     "alto"     "bajo"     "alto"    

Remover factores mediante paquete varhandle

unfactor(vector_fact_categorias)
 [1] "medio"    "alto"     "muy bajo" "medio"    "muy bajo" "muy bajo"
 [7] "medio"    "muy alto" "muy bajo" "bajo"     "bajo"     "muy alto"
[13] "muy bajo" "alto"     "muy bajo" "medio"    "muy alto" "alto"    
[19] "muy bajo" "muy alto" "alto"     "medio"    "alto"     "muy alto"
[25] "muy bajo" "bajo"     "alto"     "alto"     "bajo"     "alto"    

Remover factores de paises_america2

as.character(levels(paises_america2))[paises_america2]
 [1] "Argentina"           "Bolivia"             "Brazil"             
 [4] "Canada"              "Chile"               "Colombia"           
 [7] "Costa Rica"          "Cuba"                "Dominican Republic" 
[10] "Ecuador"             "El Salvador"         "Guatemala"          
[13] "Haiti"               "Honduras"            "Jamaica"            
[16] "Mexico"              "Nicaragua"           "Panama"             
[19] "Paraguay"            "Peru"                "Puerto Rico"        
[22] "Trinidad and Tobago" "United States"       "Uruguay"            
[25] "Venezuela"          

Parte 3: Coerce

Coerción (coerce) en R se refiere al proceso automático de conversión de un tipo de dato a otro. Esto puede ocurrir cuando se realizan operaciones entre diferentes tipos de datos, y R intenta adaptar los datos para que puedan ser utilizados juntos.

Tipos de Coerción:

  1. Coerción Implícita (Implicit Coercion): Ocurre automáticamente cuando realizas operaciones con diferentes tipos de datos.

  2. Coerción Explícita (Explicit Coercion): Se realiza manualmente utilizando funciones específicas para convertir un tipo de dato a otro.

Coerción Implícita

Cuando intentas sumar un número entero y un número decimal, R convierte el número entero en un número decimal antes de realizar la operación.

# Coerción implícita: Suma de un número entero y un número decimal
entero <- 5L
decimal <- 3.2

resultado <- entero + decimal
resultado  
[1] 8.2

En este ejemplo, entero es un número entero (integer) y decimal es un número decimal (numeric). Cuando se suman, R convierte el integer en numeric para que puedan ser sumados.

Coerción Explícita

Puedes convertir manualmente un tipo de dato a otro utilizando funciones como as.numeric(), as.character(), as.logical() y más.

# Coerción explícita: Convertir un carácter a un número decimal
numero_como_cadena <- "3.2"
numero_decimal <- as.numeric(numero_como_cadena)
numero_decimal  # Salida: 3.2
[1] 3.2
# Coerción explícita: Convertir un número entero a un carácter
entero <- 5L
cadena <- as.character(entero)
cadena  # Salida: "5"
[1] "5"

En el primer ejemplo, as.numeric() convierte la cadena "3.2" en un número decimal 3.2. En el segundo ejemplo, as.character() convierte el entero 5L en la cadena "5".

Coerción en Data Frames

Cuando se crea un data frame con columnas de diferentes tipos de datos, R intenta coercer las columnas al tipo común más amplio.

# Crear un data frame con diferentes tipos de datos
df <- data.frame(
  edad = c(25L, 30L, 35L),
  nombre = c("Juan", "Ana", "Carlos"),
  altura = c(1.75, 1.68, 1.80)
)

df
  edad nombre altura
1   25   Juan   1.75
2   30    Ana   1.68
3   35 Carlos   1.80

En este ejemplo, edad es una columna de enteros (integer), nombre es una columna de caracteres (character), y altura es una columna numérica (numeric). R convierte todas las columnas a tipo character para que puedan estar en el mismo formato.

Parte 4: Recycle

El recycle es el proceso por el cual R repite los elementos de un vector más corto hasta que pueda combinarlo con otro vector más largo. Esto ocurre cuando intentas realizar una operación entre dos vectores y uno tiene menos elementos que el otro.

Ejemplo 1: Suma de Vectores

Supongamos que tienes dos vectores:

vector_corto <- c(1, 2)
vector_largo <- c(3, 4, 5, 6)

Si intentas sumar estos vectores:

resultado <- vector_corto + vector_largo

R reciclará vector_corto para que tenga la misma longitud que vector_largo. Es decir, R repite los elementos de vector_corto hasta que coincida con la longitud de vector_largo.

El proceso sería algo así:

  • vector_corto: 1, 2
  • Repetir: 1, 2, 1, 2

Luego, realiza la suma elemento por elemento:

resultado <- c(1+3, 2+4, 1+5, 2+6)

resultado
[1] 4 6 6 8

Multiplicación de Vectores

Ahora, considera otro ejemplo con multiplicación:

vector_corto <- c(2, 3)
vector_largo <- c(5, 7, 9, 11)

Si intentas multiplicar estos vectores:

resultado <- vector_corto * vector_largo

R reciclará vector_corto:

  • vector_corto: 2, 3
  • Repetir: 2, 3, 2, 3

Luego, realiza la multiplicación elemento por elemento:

resultado <- c(2*5, 3*7, 2*9, 3*11)
resultado
[1] 10 21 18 33

Asignación de Valores

El recycle también se aplica cuando asignas valores a un vector más largo que el valor que estás asignando.

Supongamos que tienes un vector:

vector_largo <- c(0, 0, 0, 0)

Y quieres asignarle los valores de otro vector más corto:

vector_corto <- c(1, 2)
vector_largo[] <- vector_corto

R reciclará vector_corto para que tenga la misma longitud que vector_largo:

  • vector_corto: 1, 2
  • Repetir: 1, 2, 1, 2

El resultado será:

vector_largo
[1] 1 2 1 2

Consideraciones Importantes

  1. Longitud Exacta: Si el vector más corto no se puede reciclar exactamente para coincidir con la longitud del vector más largo (es decir, si no es un múltiplo), R producirá una advertencia y repetirá los elementos hasta que termine el vector más largo.
vector_corto <- c(1, 2)
vector_largo <- c(3, 4, 5)
resultado <- vector_corto + vector_largo

Esto producirá una advertencia:

Warning message:
longer object length is not a multiple of shorter object length

Y el resultado será:

resultado
[1] 4 6 6
  1. Operaciones Lógicas: El recycle también se aplica en operaciones lógicas.
vector_corto <- c(TRUE, FALSE)
vector_largo <- c(1, 2, 3, 4)
resultado <- vector_corto & (vector_largo > 2)

R reciclará vector_corto:

  • vector_corto: TRUE, FALSE
  • Repetir: TRUE, FALSE, TRUE, FALSE

Luego, realiza la operación lógica elemento por elemento:

resultado <- c(TRUE & (1 > 2), FALSE & (2 > 2), TRUE & (3 > 2), FALSE & (4 > 2))

El resultado será:

resultado
[1] FALSE FALSE  TRUE FALSE

Reciclado en una Data Frame

El recycle también se aplica cuando asignas un valor de un vector de menor lenght junto a otros en la construcción de una data frame.

df_recycle <- data.frame(vector_corto = '1',
                         vector_largo = 1:5)

df_recycle
  vector_corto vector_largo
1            1            1
2            1            2
3            1            3
4            1            4
5            1            5

El recycle es una característica de R que facilita operaciones entre vectores de diferentes longitudes. Sin embargo, es importante tener en cuenta las advertencias y asegurarse de que el reciclado produzca los resultados esperados.

Parte 5: Trabajando con Valores Faltantes

Los valores NA (que representan datos faltantes) es una tarea común en análisis de datos utilizando R. A

¿Qué son los valores NA?

Los valores NA en R representan “Not Available” y se utilizan para indicar que un dato está faltante o desconocido. Estos valores pueden surgir por diversas razones, como errores de entrada de datos, fallos en las mediciones, etc.

1. Identificación de Valores NA

Primero, es importante saber cómo identificar los valores NA en tus conjuntos de datos. Puedes usar la función is.na() para esto.

Ejemplo:

# Crear un vector con algunos valores NA
datos <- c(1, 2, NA, 4, NA, 6)

datos
[1]  1  2 NA  4 NA  6
# Identificar los valores NA
is.na(datos)
[1] FALSE FALSE  TRUE FALSE  TRUE FALSE

Contar Valores NA

Para saber cuántos valores NA hay en un conjunto de datos, puedes usar la función sum() junto con is.na().

Ejemplo:

# Contar los valores NA en el vector 'datos'
sum(is.na(datos))
[1] 2

Eliminar Valores NA

Si deseas eliminar las observaciones que contienen valores NA, puedes usar la función na.omit().

Ejemplo:

# Eliminar filas con valores NA en un data frame
df <- data.frame(a = c(1, 2, NA), b = c(4, NA, 6))
df_sin_na <- na.omit(df)
df_sin_na
  a b
1 1 4

Reemplazar Valores NA

A veces es útil reemplazar los valores NA con algún otro valor, como la media o mediana de la columna.

Ejemplo:

# Reemplazar valores NA con la media de la columna 'a'
df$a[is.na(df$a)] <- mean(df$a, na.rm = TRUE)
df
    a  b
1 1.0  4
2 2.0 NA
3 1.5  6

Manejo de Valores NA en Operaciones

Cuando realizas operaciones matemáticas, los valores NA pueden propagarse. Para evitar esto, puedes usar el parámetro na.rm = TRUE.

Ejemplo:

# Calcular la media ignorando los valores NA
mean(df$a, na.rm = TRUE)
[1] 1.5

Uso de la función complete.cases()

La función complete.cases() te permite seleccionar solo las filas que no contienen valores NA.

Ejemplo:

# Seleccionar filas sin valores NA
df_completos <- df[complete.cases(df), ]
df_completos
    a b
1 1.0 4
3 1.5 6

Funciones de Apoyo al trabajar con NA

  • Identificación: is.na()
  • Conteo: sum(is.na())
  • Eliminación: na.omit()
  • Reemplazo: [is.na(columna)] <- valor_reemplazo
  • Operaciones: na.rm = TRUE
  • Selección de casos completos: complete.cases()

Coerción de NA´s

Los NA conservan sus propiedas al ser sometidos a coerciones explícitas

as.numeric(c(1,NA))
[1]  1 NA
as.character(c('Prop',NA))
[1] "Prop" NA    
as.character(c(1,NA))
[1] "1" NA 

Ejemplo: trabajando con NA´s

Ver script

Filtrado de NA’s

Parte 6: Formatos de Datos Long y Wide

  • Formato Ancho (Wide): En este formato, cada columna representa una variable diferente y cada fila representa un caso o observación, por ejemplo un lugar o un paciente. Tendrás múltiples variables de observación, que contienen el mismo tipo de datos, para cada tema. Estas observaciones pueden ser repetidas a lo largo del tiempo, o puede ser la observación de múltiples variables (o una mezcla de ambos). Para algunas aplicaciones, es preferible el formato “ancho”. Sin embargo, muchas de las funciones de R han sido diseñadas para datos de formato “largo”.

    Para los humanos, el formato “ancho” es a menudo más intuitivo ya que podemos ver más de los datos en la pantalla debido a su forma. Sin embargo, el formato “largo” es más legible para las máquinas y está más cerca al formateo de las bases de datos. Las variables de ID en nuestras data frames son similares a los campos en una base de datos y las variables observadas son como los valores de la base de datos.

  • Formato Largo (Long): En este formato, todas las variables están en una sola columna, y cada fila representa una combinación única de caso y variable. El formato “largo” es donde:

    • cada columna es una variable

    • cada fila es una observación

    En el formato “largo”, generalmente tienes una columna para la variable observada y las otras columnas son variables de ID.

Explicación Gráfica:

Formatos Wide y Long

Imagen obtenida de swcarpentry.github.io

Proceso de Conversión de Wide a Long

pivot_longer(cols = starts_with("a"),
             names_to = "key",
             values_to = "value")

Imagen obtenida de swcarpentry.github.io

Material complementario: en la página https://swcarpentry.github.io/r-novice-gapminder-es/14-tidyr.html hay informaciones complementarias sobre estos formatos.

De dplyr a tidyr

Para trabajar con estas estructuras de datos y poder convertirlas de un formato long a widder o viceversa, es necesario incorporar en nuestra caja de herramientas el paquete tidyr que también se encuentra incluido en la suite tidyverse.

Creando Tibbles

Primero, vamos a crear algunos ejemplos de tibbles en R utilizando el paquete dplyr y tidyverse.

library(tidyverse)

# Crear un tibble ancho (wide)
datos_ancho <- tribble(
  ~nombre, ~edad_2015, ~edad_2016, ~edad_2017,
  "Juan",   20,         21,         22,
  "Ana",    23,         24,         25
)


datos_ancho
# A tibble: 2 × 4
  nombre edad_2015 edad_2016 edad_2017
  <chr>      <dbl>     <dbl>     <dbl>
1 Juan          20        21        22
2 Ana           23        24        25
# Crear un tibble largo (long)
datos_largo <- tribble(
  ~nombre, ~año, ~edad,
  "Juan",   2015, 20,
  "Juan",   2016, 21,
  "Juan",   2017, 22,
  "Ana",    2015, 23,
  "Ana",    2016, 24,
  "Ana",    2017, 25
)

datos_largo
# A tibble: 6 × 3
  nombre   año  edad
  <chr>  <dbl> <dbl>
1 Juan    2015    20
2 Juan    2016    21
3 Juan    2017    22
4 Ana     2015    23
5 Ana     2016    24
6 Ana     2017    25

Cambiando de Wide a Long

Para transformar un tibble ancho en largo, se utiliza la función pivot_longer() del paquete tidyr.

# Convertir datos_ancho a datos_largo
datos_largo <- datos_ancho %>%
  pivot_longer(cols = starts_with("edad"),
               names_to = "año",
               values_to = "edad")

datos_largo
# A tibble: 6 × 3
  nombre año        edad
  <chr>  <chr>     <dbl>
1 Juan   edad_2015    20
2 Juan   edad_2016    21
3 Juan   edad_2017    22
4 Ana    edad_2015    23
5 Ana    edad_2016    24
6 Ana    edad_2017    25

Cambiando de Long a Wide

Para transformar un tibble largo en ancho, se utiliza la función pivot_wider() del paquete tidyr.

# Convertir datos_largo a datos_ancho
datos_ancho <- datos_largo %>%
  pivot_wider(names_from = año,
               values_from = edad)

datos_ancho
# A tibble: 2 × 4
  nombre edad_2015 edad_2016 edad_2017
  <chr>      <dbl>     <dbl>     <dbl>
1 Juan          20        21        22
2 Ana           23        24        25

Explicación de las Funciones

  • pivot_longer(): Esta función se utiliza para convertir un tibble ancho en largo. Los argumentos principales son:
    • cols: Especifica qué columnas se deben convertir a formato largo.
    • names_to: Define el nombre de la nueva columna que contendrá los nombres originales de las columnas.
    • values_to: Define el nombre de la nueva columna que contendrá los valores.
  • pivot_wider(): Esta función se utiliza para convertir un tibble largo en ancho. Los argumentos principales son:
    • names_from: Especifica qué columna contiene los nombres de las nuevas columnas.
    • values_from: Especifica qué columna contiene los valores que se asignarán a las nuevas columnas.

Ventajas y Uso

  • Formato Ancho (Wide):
    • Ventaja: Facilita visualizar y comparar múltiples variables en una sola tabla.
    • Uso: Útil cuando se necesita comparar fácilmente distintos valores de la misma variable para diferentes casos.
  • Formato Largo (Long):
    • Ventaja: Permite realizar análisis estadísticos más complejos, como modelos de series temporales o análisís longitudinales.
    • Uso: Útil cuando se necesita realizar operaciones que requieren agrupar datos por una variable y luego aplicar funciones a los valores correspondientes.

Ejemplo Práctico

Supongamos que tienes un conjunto de datos sobre las ventas de diferentes productos en varios meses. Quieres analizar cómo ha evolucionado la venta de cada producto a lo largo del tiempo.

# Datos ancho (ejemplo)
ventas_ancho <- tribble(
  ~producto, ~enero, ~febrero, ~marzo,
  "A",        100,    200,      150,
  "B",        120,    220,      180
)

ventas_ancho
# A tibble: 2 × 4
  producto enero febrero marzo
  <chr>    <dbl>   <dbl> <dbl>
1 A          100     200   150
2 B          120     220   180
# Convertir a formato largo
ventas_largo <- ventas_ancho %>%
  pivot_longer(cols = starts_with("enero"),
               names_to = "mes",
               values_to = "venta")

ventas_largo
# A tibble: 2 × 5
  producto febrero marzo mes   venta
  <chr>      <dbl> <dbl> <chr> <dbl>
1 A            200   150 enero   100
2 B            220   180 enero   120

Con el tibble en formato largo, puedes fácilmente calcular la tendencia de las ventas para cada producto utilizando funciones como group_by() y summarize().

# Calcular promedio de ventas por producto
promedio_ventas <- ventas_largo %>%
  group_by(producto) %>%
  summarize(promedio = mean(venta))

promedio_ventas
# A tibble: 2 × 2
  producto promedio
  <chr>       <dbl>
1 A             100
2 B             120

Ejercicios Pivots Longer:

Simulación de Precios de Accciones

En formato wider esta sería la df:

## Ejemplo promedio acciones

precio_acciones <- tibble(
  fecha = as.Date("2024-01-01") + 0:9,
  precio_x = rnorm(10, 0, 1),
  precio_y = rnorm(10, 0, 2),
  precio_z = rnorm(10, 0, 4)
)

precio_acciones
# A tibble: 10 × 4
   fecha      precio_x precio_y precio_z
   <date>        <dbl>    <dbl>    <dbl>
 1 2024-01-01   0.590     2.08    1.92  
 2 2024-01-02   0.750     1.51   -0.134 
 3 2024-01-03   0.360    -1.70   -1.20  
 4 2024-01-04  -2.11      0.330   0.998 
 5 2024-01-05   1.52      4.25   -2.81  
 6 2024-01-06  -1.24     -3.50    0.0768
 7 2024-01-07   0.222     1.22   -2.61  
 8 2024-01-08  -0.148    -2.33    0.299 
 9 2024-01-09   0.665     2.16   -3.32  
10 2024-01-10   0.0623   -0.221   2.00  

Anteriormente en tidyr la función usada para convertir los datos a formanto longer era gather

# versión anterior con gather
precio_acciones %>% 
  gather("accion_nombe",
         "precio_accion",
         -fecha)
# A tibble: 30 × 3
   fecha      accion_nombe precio_accion
   <date>     <chr>                <dbl>
 1 2024-01-01 precio_x            0.590 
 2 2024-01-02 precio_x            0.750 
 3 2024-01-03 precio_x            0.360 
 4 2024-01-04 precio_x           -2.11  
 5 2024-01-05 precio_x            1.52  
 6 2024-01-06 precio_x           -1.24  
 7 2024-01-07 precio_x            0.222 
 8 2024-01-08 precio_x           -0.148 
 9 2024-01-09 precio_x            0.665 
10 2024-01-10 precio_x            0.0623
# ℹ 20 more rows

Precios de acciones en formato longer mediante el uso de pivot_longer

# acciones pivot_longer
precio_acciones %>% 
  pivot_longer(cols = starts_with("precio"),
               names_to = "accion_nombre",
               values_to = "precio_accion")%>%
  print(n=23)
# A tibble: 30 × 3
   fecha      accion_nombre precio_accion
   <date>     <chr>                 <dbl>
 1 2024-01-01 precio_x             0.590 
 2 2024-01-01 precio_y             2.08  
 3 2024-01-01 precio_z             1.92  
 4 2024-01-02 precio_x             0.750 
 5 2024-01-02 precio_y             1.51  
 6 2024-01-02 precio_z            -0.134 
 7 2024-01-03 precio_x             0.360 
 8 2024-01-03 precio_y            -1.70  
 9 2024-01-03 precio_z            -1.20  
10 2024-01-04 precio_x            -2.11  
11 2024-01-04 precio_y             0.330 
12 2024-01-04 precio_z             0.998 
13 2024-01-05 precio_x             1.52  
14 2024-01-05 precio_y             4.25  
15 2024-01-05 precio_z            -2.81  
16 2024-01-06 precio_x            -1.24  
17 2024-01-06 precio_y            -3.50  
18 2024-01-06 precio_z             0.0768
19 2024-01-07 precio_x             0.222 
20 2024-01-07 precio_y             1.22  
21 2024-01-07 precio_z            -2.61  
22 2024-01-08 precio_x            -0.148 
23 2024-01-08 precio_y            -2.33  
# ℹ 7 more rows

Ingresos Anuales según Religión o Creencia Practicada:

Información basada en una encuesta sobre religión/creencia e ingresos obtenidos

# caso relig income
head(relig_income)
# A tibble: 6 × 11
  religion  `<$10k` `$10-20k` `$20-30k` `$30-40k` `$40-50k` `$50-75k` `$75-100k`
  <chr>       <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>      <dbl>
1 Agnostic       27        34        60        81        76       137        122
2 Atheist        12        27        37        52        35        70         73
3 Buddhist       27        21        30        34        33        58         62
4 Catholic      418       617       732       670       638      1116        949
5 Don’t kn…      15        14        15        11        10        35         21
6 Evangeli…     575       869      1064       982       881      1486        949
# ℹ 3 more variables: `$100-150k` <dbl>, `>150k` <dbl>,
#   `Don't know/refused` <dbl>
relig_income %>%
  pivot_longer(cols =!religion, 
               names_to = "income", 
               values_to = "count")
# A tibble: 180 × 3
   religion income             count
   <chr>    <chr>              <dbl>
 1 Agnostic <$10k                 27
 2 Agnostic $10-20k               34
 3 Agnostic $20-30k               60
 4 Agnostic $30-40k               81
 5 Agnostic $40-50k               76
 6 Agnostic $50-75k              137
 7 Agnostic $75-100k             122
 8 Agnostic $100-150k            109
 9 Agnostic >150k                 84
10 Agnostic Don't know/refused    96
# ℹ 170 more rows

Cartelera de Éxitos Billoard:

# caso éxitos Billboard
head(billboard)
# A tibble: 6 × 79
  artist      track date.entered   wk1   wk2   wk3   wk4   wk5   wk6   wk7   wk8
  <chr>       <chr> <date>       <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2 Pac       Baby… 2000-02-26      87    82    72    77    87    94    99    NA
2 2Ge+her     The … 2000-09-02      91    87    92    NA    NA    NA    NA    NA
3 3 Doors Do… Kryp… 2000-04-08      81    70    68    67    66    57    54    53
4 3 Doors Do… Loser 2000-10-21      76    76    72    69    67    65    55    59
5 504 Boyz    Wobb… 2000-04-15      57    34    25    17    17    31    36    49
6 98^0        Give… 2000-08-19      51    39    34    26    26    19     2     2
# ℹ 68 more variables: wk9 <dbl>, wk10 <dbl>, wk11 <dbl>, wk12 <dbl>,
#   wk13 <dbl>, wk14 <dbl>, wk15 <dbl>, wk16 <dbl>, wk17 <dbl>, wk18 <dbl>,
#   wk19 <dbl>, wk20 <dbl>, wk21 <dbl>, wk22 <dbl>, wk23 <dbl>, wk24 <dbl>,
#   wk25 <dbl>, wk26 <dbl>, wk27 <dbl>, wk28 <dbl>, wk29 <dbl>, wk30 <dbl>,
#   wk31 <dbl>, wk32 <dbl>, wk33 <dbl>, wk34 <dbl>, wk35 <dbl>, wk36 <dbl>,
#   wk37 <dbl>, wk38 <dbl>, wk39 <dbl>, wk40 <dbl>, wk41 <dbl>, wk42 <dbl>,
#   wk43 <dbl>, wk44 <dbl>, wk45 <dbl>, wk46 <dbl>, wk47 <dbl>, wk48 <dbl>, …
dim(billboard)
[1] 317  79
billboard %>%
  pivot_longer(
    cols = starts_with("wk"),
    names_to = "week",
    # names_prefix = "wk",
    values_to = "rank",
    values_drop_na = TRUE
  )
# A tibble: 5,307 × 5
   artist  track                   date.entered week   rank
   <chr>   <chr>                   <date>       <chr> <dbl>
 1 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk1      87
 2 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk2      82
 3 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk3      72
 4 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk4      77
 5 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk5      87
 6 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk6      94
 7 2 Pac   Baby Don't Cry (Keep... 2000-02-26   wk7      99
 8 2Ge+her The Hardest Part Of ... 2000-09-02   wk1      91
 9 2Ge+her The Hardest Part Of ... 2000-09-02   wk2      87
10 2Ge+her The Hardest Part Of ... 2000-09-02   wk3      92
# ℹ 5,297 more rows

Añadir prefijo a remover en la columna de destino

## remover prefijos wk
billboard %>%
  pivot_longer(
    cols = starts_with("wk"),
    names_to = "week",
    names_prefix = "wk",
    values_to = "rank",
    values_drop_na = TRUE
  )
# A tibble: 5,307 × 5
   artist  track                   date.entered week   rank
   <chr>   <chr>                   <date>       <chr> <dbl>
 1 2 Pac   Baby Don't Cry (Keep... 2000-02-26   1        87
 2 2 Pac   Baby Don't Cry (Keep... 2000-02-26   2        82
 3 2 Pac   Baby Don't Cry (Keep... 2000-02-26   3        72
 4 2 Pac   Baby Don't Cry (Keep... 2000-02-26   4        77
 5 2 Pac   Baby Don't Cry (Keep... 2000-02-26   5        87
 6 2 Pac   Baby Don't Cry (Keep... 2000-02-26   6        94
 7 2 Pac   Baby Don't Cry (Keep... 2000-02-26   7        99
 8 2Ge+her The Hardest Part Of ... 2000-09-02   1        91
 9 2Ge+her The Hardest Part Of ... 2000-09-02   2        87
10 2Ge+her The Hardest Part Of ... 2000-09-02   3        92
# ℹ 5,297 more rows

Informe Mundial Tuberculosis:

Un subconjunto de datos del Informe Mundial sobre la Tuberculosis de la Organización Mundial de la Salud. que utiliza los códigos originales de la Organización Mundial de la Salud.

Inspección Datos Entrada

# Caso WHO
names(who)
 [1] "country"      "iso2"         "iso3"         "year"         "new_sp_m014" 
 [6] "new_sp_m1524" "new_sp_m2534" "new_sp_m3544" "new_sp_m4554" "new_sp_m5564"
[11] "new_sp_m65"   "new_sp_f014"  "new_sp_f1524" "new_sp_f2534" "new_sp_f3544"
[16] "new_sp_f4554" "new_sp_f5564" "new_sp_f65"   "new_sn_m014"  "new_sn_m1524"
[21] "new_sn_m2534" "new_sn_m3544" "new_sn_m4554" "new_sn_m5564" "new_sn_m65"  
[26] "new_sn_f014"  "new_sn_f1524" "new_sn_f2534" "new_sn_f3544" "new_sn_f4554"
[31] "new_sn_f5564" "new_sn_f65"   "new_ep_m014"  "new_ep_m1524" "new_ep_m2534"
[36] "new_ep_m3544" "new_ep_m4554" "new_ep_m5564" "new_ep_m65"   "new_ep_f014" 
[41] "new_ep_f1524" "new_ep_f2534" "new_ep_f3544" "new_ep_f4554" "new_ep_f5564"
[46] "new_ep_f65"   "newrel_m014"  "newrel_m1524" "newrel_m2534" "newrel_m3544"
[51] "newrel_m4554" "newrel_m5564" "newrel_m65"   "newrel_f014"  "newrel_f1524"
[56] "newrel_f2534" "newrel_f3544" "newrel_f4554" "newrel_f5564" "newrel_f65"  
dim(who)
[1] 7240   60
head(who[,1:10])
# A tibble: 6 × 10
  country   iso2  iso3   year new_sp_m014 new_sp_m1524 new_sp_m2534 new_sp_m3544
  <chr>     <chr> <chr> <dbl>       <dbl>        <dbl>        <dbl>        <dbl>
1 Afghanis… AF    AFG    1980          NA           NA           NA           NA
2 Afghanis… AF    AFG    1981          NA           NA           NA           NA
3 Afghanis… AF    AFG    1982          NA           NA           NA           NA
4 Afghanis… AF    AFG    1983          NA           NA           NA           NA
5 Afghanis… AF    AFG    1984          NA           NA           NA           NA
6 Afghanis… AF    AFG    1985          NA           NA           NA           NA
# ℹ 2 more variables: new_sp_m4554 <dbl>, new_sp_m5564 <dbl>

Convertir a formato longer

who %>% 
  pivot_longer(
    cols = new_sp_m014:newrel_f65,
    names_to = c("diagnosis", "gender", "age"),
    names_pattern = "new_?(.*)_(.)(.*)",
    values_to = "count"
  )
# A tibble: 405,440 × 8
   country     iso2  iso3   year diagnosis gender age   count
   <chr>       <chr> <chr> <dbl> <chr>     <chr>  <chr> <dbl>
 1 Afghanistan AF    AFG    1980 sp        m      014      NA
 2 Afghanistan AF    AFG    1980 sp        m      1524     NA
 3 Afghanistan AF    AFG    1980 sp        m      2534     NA
 4 Afghanistan AF    AFG    1980 sp        m      3544     NA
 5 Afghanistan AF    AFG    1980 sp        m      4554     NA
 6 Afghanistan AF    AFG    1980 sp        m      5564     NA
 7 Afghanistan AF    AFG    1980 sp        m      65       NA
 8 Afghanistan AF    AFG    1980 sp        f      014      NA
 9 Afghanistan AF    AFG    1980 sp        f      1524     NA
10 Afghanistan AF    AFG    1980 sp        f      2534     NA
# ℹ 405,430 more rows

Análisis patrón usado en names_pattern

library(stringr) # ya está cargada en tidyverse
str_split("new_sp_m2534", "new_?(.*)_(.)(.*)")
[[1]]
[1] "" ""
# Hacer consultar a LLM sobre este patrón
cadena <- "new_user_123"
patron <- "new_?(.*)_(.)(.*)"

resultados <- str_match(cadena, patron)
resultados
     [,1]           [,2]   [,3] [,4]
[1,] "new_user_123" "user" "1"  "23"

Ejercicios Pivots Widder:

Peces en Ríos

Información sobre los peces que nadan por un río: cada estación representa un monitor autónomo que registra si un pez marcado ha sido visto en ese lugar.

######## pivot_wider()
head(fish_encounters, 8)
# A tibble: 8 × 3
  fish  station  seen
  <fct> <fct>   <int>
1 4842  Release     1
2 4842  I80_1       1
3 4842  Lisbon      1
4 4842  Rstr        1
5 4842  Base_TD     1
6 4842  BCE         1
7 4842  BCW         1
8 4842  BCE2        1
fish_encounters %>%
  pivot_wider(names_from = station, 
              values_from = seen)
# A tibble: 19 × 12
   fish  Release I80_1 Lisbon  Rstr Base_TD   BCE   BCW  BCE2  BCW2   MAE   MAW
   <fct>   <int> <int>  <int> <int>   <int> <int> <int> <int> <int> <int> <int>
 1 4842        1     1      1     1       1     1     1     1     1     1     1
 2 4843        1     1      1     1       1     1     1     1     1     1     1
 3 4844        1     1      1     1       1     1     1     1     1     1     1
 4 4845        1     1      1     1       1    NA    NA    NA    NA    NA    NA
 5 4847        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA
 6 4848        1     1      1     1      NA    NA    NA    NA    NA    NA    NA
 7 4849        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
 8 4850        1     1     NA     1       1     1     1    NA    NA    NA    NA
 9 4851        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
10 4854        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
11 4855        1     1      1     1       1    NA    NA    NA    NA    NA    NA
12 4857        1     1      1     1       1     1     1     1     1    NA    NA
13 4858        1     1      1     1       1     1     1     1     1     1     1
14 4859        1     1      1     1       1    NA    NA    NA    NA    NA    NA
15 4861        1     1      1     1       1     1     1     1     1     1     1
16 4862        1     1      1     1       1     1     1     1     1    NA    NA
17 4863        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
18 4864        1     1     NA    NA      NA    NA    NA    NA    NA    NA    NA
19 4865        1     1      1    NA      NA    NA    NA    NA    NA    NA    NA

Análisis Gapminder

¿Cuál estructura (longer o widder) tiene el conjunto de datos Gapminder?

head(df_gapminder_csv)
# A tibble: 6 × 6
  country     continent  year lifeExp      pop gdpPercap
  <chr>       <chr>     <int>   <dbl>    <int>     <dbl>
1 Afghanistan Asia       1952    28.8  8425333      779.
2 Afghanistan Asia       1957    30.3  9240934      821.
3 Afghanistan Asia       1962    32.0 10267083      853.
4 Afghanistan Asia       1967    34.0 11537966      836.
5 Afghanistan Asia       1972    36.1 13079460      740.
6 Afghanistan Asia       1977    38.4 14880372      786.

Consideraciones Finales

Entender los formatos de datos long y wide es crucial para trabajar eficazmente con datos en R. Dependiendo del análisis que quieras realizar, uno de estos formatos puede ser más apropiado que el otro. Afortunadamente, las funciones pivot_longer() y pivot_wider() facilitan la transición entre ambos formatos.